package com.nbjtjc.safe.service.sys;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nbjtjc.common.exception.ValidateException;
import com.nbjtjc.safe.bean.Page;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.mapper.sys.SysDeptMapper;
import com.nbjtjc.safe.mapper.sys.SysNoticeMapper;
import com.nbjtjc.safe.mapper.sys.SysNoticeTargetMapper;
import com.nbjtjc.safe.mapper.sys.SysUserMapper;
import com.nbjtjc.safe.model.sys.SysGroup;
import com.nbjtjc.safe.model.sys.SysNotice;
import com.nbjtjc.safe.model.sys.SysNoticeTarget;
import com.nbjtjc.safe.model.sys.SysUser;
import com.nbjtjc.safe.util.MyShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysNoticeService {
    @Autowired
    private SysNoticeMapper sysNoticeMapper;
    @Autowired
    private SysNoticeTargetMapper sysNoticeTargetMapper;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private SysUserMapper sysUserMapper;

    public Result find(SysNotice sysNotice, Page page) {
        Result result = new Result();
        PageHelper.startPage(page.getPageCurrent(), page.getPageSize());
        List<SysNotice> sysNotices = sysNoticeMapper.search(sysNotice, page, null);
        result.setData(new PageInfo<>(sysNotices));
        return result;
    }


    public SysNotice add(SysNotice sysNotice) {
        Result result = new Result<>();
        if (ObjectUtil.isNull(sysNotice) || ObjectUtil.isNull(sysNotice.getContent())) {
            result.setFalse("插入不能为空");
            throw new ValidateException("插入不能为空");

        }
        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("user");
        sysNotice.setDeptId(sysUser.getDeptId().intValue());
        sysNotice.setCompanyId(sysUser.getCompanyId().intValue());
        sysNotice.setWriteUserId(sysUser.getUserId());
        sysNotice.setCreateTime(new Date());
        int res = sysNoticeMapper.insert(sysNotice);
        if (res == 0) {
            result.setFalse("从插入失败");
            throw new ValidateException("从插入失败");
        }
        return sysNotice;
    }

    /**
     * @param sysNotice 通知模板，标题等基本信息
     * @param userIds   需要通知的对象
     * @return
     */
    public boolean addNoticeList(SysNotice sysNotice, List<Integer> userIds) {
        sysNoticeMapper.insertSelective(sysNotice);
        List<SysNoticeTarget> sysNoticeTargets = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userIds)) {
            userIds.forEach(userId -> {
                SysNoticeTarget sysNoticeTarget = new SysNoticeTarget();
                sysNoticeTarget.setTargetUserId(userId);
                sysNoticeTarget.setCreateTime(new Date());
                sysNoticeTarget.setHasRead(false);
                sysNoticeTarget.setSysNoticeId(sysNotice.getnId());
                sysNoticeTargets.add(sysNoticeTarget);
            });
        }
        if (CollectionUtil.isNotEmpty(sysNoticeTargets)) {
            sysNoticeTargetMapper.insertList(sysNoticeTargets);
        }
        return true;
    }

    /**
     * 发布通知，通知人员为当前公司加上所有下级子公司的员工
     *
     * @param sysNotice
     * @param companyId 发布人当前的公司
     * @return
     */
    public boolean addNotice(SysNotice sysNotice, Integer companyId) {
        List<Integer> subCompanyIds = new ArrayList<>();
        subCompanyIds = sysDeptService.getAllSubCompanyId(companyId, subCompanyIds);
        subCompanyIds.add(companyId);
        List<Integer> userIds = sysUserMapper.findUserIdsByCompanyIds(subCompanyIds);
        return addNoticeList(sysNotice,userIds);
    }


    public Result<Boolean> delete(SysNotice sysNotice) {
        Result<Boolean> result = new Result<>();
        int res = 0;
        res = sysNoticeMapper.delete(sysNotice);
        if (res == 0) {
            result.setFalse("删除失败");
        }
        return result;
    }

    public Result update(SysNotice sysNotice) {
        Result result = new Result<>();
        if (ObjectUtil.isNull(sysNotice) || ObjectUtil.isNull(sysNotice.getnId())) {
            result.setFalse("更新不能为空");
            return result;
        }
        int res = sysNoticeMapper.updateByPrimaryKeySelective(sysNotice);
        if (res == 0) {
            result.setFalse("更新失败");
            return result;
        }
        result.setData(sysNotice);
        return result;
    }

    public Integer getUnReadNoticeCount(){
        int unReadCount=sysNoticeTargetMapper.findCountByUserId(MyShiroUtils.getSessionUserId(),false);
        return unReadCount;
    }

    public PageInfo getMyNotice(Boolean hasRead, Page page) {
        PageHelper.startPage(page.getPageCurrent(), page.getPageSize());
        List<SysNoticeTarget> sysNoticeTargets = sysNoticeTargetMapper
                .findNoticeByUserId(MyShiroUtils.getSessionUserId());
        PageInfo pageInfo = new PageInfo<>(sysNoticeTargets);
        List<Integer> sysNoticeIds = sysNoticeTargets.stream()
                .map(SysNoticeTarget::getSysNoticeId).collect(Collectors.toList());
        List<SysNotice> sysNotices = sysNoticeMapper.search(null, null, sysNoticeIds);
        if (CollectionUtil.isEmpty(sysNotices)) {
            return new PageInfo();
        }
        Map<Integer, SysNotice> sysNoticeMap = sysNotices.stream()
                .collect(Collectors.toMap(SysNotice::getnId, notice -> notice));
        sysNoticeTargets.forEach(sysNoticeTarget -> {
            sysNoticeTarget.setSysNotice(sysNoticeMap.get(sysNoticeTarget.getSysNoticeId()));
        });
        return pageInfo;
    }

    /**
     * 阅读通知，更新通知状态为已读，更新通知阅读数量
     *
     * @param sysNoticeTargetId
     * @param noticeId
     * @return
     */
    @Transactional
    public Result readNotice(int sysNoticeTargetId, int noticeId) {
        Result result = new Result();
        SysNoticeTarget sysNoticeTarget = new SysNoticeTarget();
        sysNoticeTarget.setHasRead(true);
        sysNoticeTarget.setId(sysNoticeTargetId);
        sysNoticeTarget.setReadTime(new Date());
        sysNoticeTargetMapper.updateByPrimaryKeySelective(sysNoticeTarget);
        return result;
    }

}
